/*
 * steppers.h
 *
 * Copyright 2011 Pieter Agten
 *
 * This file is part of Yarf.
 *
 * Yarf is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Yarf is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Yarf.  If not, see <http://www.gnu.org/licenses/>.
 */

/**
 * @file   steppers.h
 * @author Pieter Agten (pieter.agten@gmail.com)
 * @date   22 sep 2011
 * @brief  Stepper motor initialization and control.
 */

#ifndef STEPPERS_H
#define STEPPERS_H

#include "yarf.h"
#include "fastio.h"


/**
 * Enables the x-axis stepper motor.
 */
#define stepper_enable_x() WRITE(X_ENABLE_PIN, !X_ENABLE_INVERTED)
/**
 * Enables the y-axis stepper motor.
 */
#define stepper_enable_y() WRITE(Y_ENABLE_PIN, !Y_ENABLE_INVERTED)
/**
 * Enables the z-axis stepper motor.
 */
#define stepper_enable_z() WRITE(Z_ENABLE_PIN, !Z_ENABLE_INVERTED)
/**
 * Enables the e-axis stepper motor.
 */
#define stepper_enable_e() WRITE(E_ENABLE_PIN, !E_ENABLE_INVERTED)

/**
 * Disables the x-axis stepper motor.
 */
#define stepper_disable_x() WRITE(X_ENABLE_PIN, X_ENABLE_INVERTED)
/**
 * Disables the y-axis stepper motor.
 */
#define stepper_disable_y() WRITE(Y_ENABLE_PIN, Y_ENABLE_INVERTED)
/**
 * Disables the z-axis stepper motor.
 */
#define stepper_disable_z() WRITE(Z_ENABLE_PIN, Z_ENABLE_INVERTED)
/**
 * Disables the e-axis stepper motor.
 */
#define stepper_disable_e() WRITE(E_ENABLE_PIN, E_ENABLE_INVERTED)

/**
 * Sets up the x-axis stepper motor to step in the positive direction.
 */
#define stepper_x_dir_pos() WRITE(X_DIR_PIN, !X_DIR_INVERTED)
/**
 * Sets up the y-axis stepper motor to step in the positive direction.
 */
#define stepper_y_dir_pos() WRITE(Y_DIR_PIN, !Y_DIR_INVERTED)
/**
 * Sets up the z-axis stepper motor to step in the positive direction.
 */
#define stepper_z_dir_pos() WRITE(Z_DIR_PIN, !Z_DIR_INVERTED)
/**
 * Sets up the e-axis stepper motor to step in the positive direction.
 */
#define stepper_e_dir_pos() WRITE(E_DIR_PIN, !E_DIR_INVERTED)

/**
 * Sets up the x-axis stepper motor to step in the negative direction.
 */
#define stepper_x_dir_neg() WRITE(X_DIR_PIN, X_DIR_INVERTED)
/**
 * Sets up the y-axis stepper motor to step in the negative direction.
 */
#define stepper_y_dir_neg() WRITE(Y_DIR_PIN, Y_DIR_INVERTED)
/**
 * Sets up the z-axis stepper motor to step in the negative direction.
 */
#define stepper_z_dir_neg() WRITE(Z_DIR_PIN, Z_DIR_INVERTED)
/**
 * Sets up the e-axis stepper motor to step in the negative direction.
 */
#define stepper_e_dir_neg() WRITE(E_DIR_PIN, E_DIR_INVERTED)

/**
 * Sets the x-axis stepper motor step signal.
 */
#define stepper_x_step_high() WRITE(X_STEP_PIN, !X_STEP_INVERTED)
/**
 * Clears the x-axis stepper motor step signal.
 */
#define stepper_x_step_low() WRITE(X_STEP_PIN,   X_STEP_INVERTED)

/**
 * Sets the y-axis stepper motor step signal.
 */
#define stepper_y_step_high() WRITE(Y_STEP_PIN, !Y_STEP_INVERTED)
/**
 * Clears the y-axis stepper motor step signal.
 */
#define stepper_y_step_low() WRITE(Y_STEP_PIN,   Y_STEP_INVERTED)

/**
 * Sets the z-axis stepper motor step signal.
 */
#define stepper_z_step_high() WRITE(Z_STEP_PIN, !Z_STEP_INVERTED)
/**
 * Clears the z-axis stepper motor step signal.
 */
#define stepper_z_step_low() WRITE(Z_STEP_PIN,   Z_STEP_INVERTED)

/**
 * Sets the e-axis stepper motor step signal.
 */
#define stepper_e_step_high() WRITE(E_STEP_PIN, !E_STEP_INVERTED)
/**
 * Clears the e-axis stepper motor step signal.
 */
#define stepper_e_step_low() WRITE(E_STEP_PIN,   E_STEP_INVERTED)


/**
 * Enables a specific stepper motor.
 *
 * @param axis the axis of which to enable the stepper motor
 */
static inline void
stepper_enable(unsigned char axis) {
  switch(axis) {
    case X_AXIS:
      stepper_enable_x();
      break;
    case Y_AXIS:
      stepper_enable_y();
      break;
    case Z_AXIS:
      stepper_enable_z();
      break;
    case E_AXIS:
      stepper_enable_e();
      break;
  }
}

/**
 * Disables a specific stepper motor.
 *
 * @param axis the axis of which to disable the stepper motor
 */
static inline void
stepper_disable(unsigned char axis) {
  switch(axis) {
    case X_AXIS:
      stepper_disable_x();
      break;
    case Y_AXIS:
      stepper_disable_y();
      break;
    case Z_AXIS:
      stepper_disable_z();
      break;
    case E_AXIS:
      stepper_disable_e();
      break;
  }
}

/**
 * Sets up a specific stepper motor to step in the positive direction.
 *
 * @param axis the axis of which to set up the stepper motor to step in the
 *             positive direction
 */
static inline void
stepper_dir_pos(unsigned char axis) {
  switch(axis) {
    case X_AXIS:
      stepper_x_dir_pos();
      break;
    case Y_AXIS:
      stepper_y_dir_pos();
      break;
    case Z_AXIS:
      stepper_z_dir_pos();
      break;
    case E_AXIS:
      stepper_e_dir_pos();
      break;
  }
}

/**
 * Sets up a specific stepper motor to step in the negative direction.
 *
 * @param axis the axis of which to set up the stepper motor to step in the
 *             negative direction
 */
static inline void
stepper_dir_neg(unsigned char axis) {
  switch(axis) {
    case X_AXIS:
      stepper_x_dir_neg();
      break;
    case Y_AXIS:
      stepper_y_dir_neg();
      break;
    case Z_AXIS:
      stepper_z_dir_neg();
      break;
    case E_AXIS:
      stepper_e_dir_neg();
      break;
  }
}

/**
 * Sets the enable signal of a specific stepper motor.
 *
 * @param axis the axis of which to set the stepper motor's enable signal
 */
static inline void
stepper_step_high(unsigned char axis) {
  switch(axis) {
    case X_AXIS:
      stepper_x_step_high();
      break;
    case Y_AXIS:
      stepper_y_step_high();
      break;
    case Z_AXIS:
      stepper_z_step_high();
      break;
    case E_AXIS:
      stepper_e_step_high();
      break;
  }
}

/**
 * Clears the enable signal of a specific stepper motor.
 *
 * @param axis the axis of which to clear the stepper motor's enable signal
 */
static inline void
stepper_step_low(unsigned char axis) {
  switch(axis) {
    case X_AXIS:
      stepper_x_step_low();
      break;
    case Y_AXIS:
      stepper_y_step_low();
      break;
    case Z_AXIS:
      stepper_z_step_low();
      break;
    case E_AXIS:
      stepper_e_step_low();
      break;
  }
}

/**
 * Initializes the stepper motors.
 */
void steppers_init(void);

/**
 * Disables all stepper motors.
 */
void steppers_disable(void);


#endif //STEPPERS_H
